<template>
  <view class="" style="width: 100%">
    <view class="video-wrapper" v-if="readonly">
      <ve-video :url="videoObj.openUrl" v-if="videoObj">
        <image
          v-if="!readonly"
          class="cover-image"
          src="../../../static/icons/img-delete.png"
          style="position: absolute; top: 10px; right: 10px; width: 24px; height: 24px; z-index: 9"
          @tap="delVideo"
        >
        </image>
      </ve-video>
      <view class="empty-block" v-else>
        <view class="empty-block-wrap">
          <view class="empty-block-inner">
            <ve-image src="empty" class="empty_img" width="64" height="64" />
            <p class="empty_text">暂无数据</p>
          </view>
        </view>
      </view>
    </view>
    <view class="video-wrapper" v-else>
      <ve-video :url="videoObj.openUrl" v-if="videoObj">
        <image
          v-if="!readonly"
          class="cover-image"
          src="../../../static/icons/img-delete.png"
          style="position: absolute; top: 10px; right: 10px; width: 24px; height: 24px; z-index: 9"
          @tap="delVideo"
        >
        </image>
      </ve-video>
      <view class="upload-wrapper" v-if="!readonly && !videoObj">
        <view class="upload flex-row-center" @click="upMaintainVideo()">
          <!-- <ve-icon name="add_btn" size="41" /> -->
          <image class="add_btn" src="../../../static/images/upload.png" mode="widthFix"></image>
          <view class="tips">
            <view class="tips-text">为防止视频过大影响上传速度，拍摄视频时</view>
            <view class="tips-text red">请勿用高像素或4K拍摄，1G视频压缩约1~3分钟</view>
          </view>
        </view>
      </view>
      <!-- 上传进度 -->
      <ve-modal title="上传中" v-model="progressInfo.visible" :showConfirm="false" :showCancel="false" :maskClose="false">
        <progress :percent="progressInfo.percent" show-info stroke-width="3" />
        <template v-slot:footer>
          <ve-button type="primary" @tap="cancelUpload()">取消上传</ve-button>
        </template>
      </ve-modal>
    </view>

    <!-- 调试信息 -->
    <view class="u-toast-container" v-if="compreeRecorder.visible && showLog">
      <view>原大小：{{ compreeRecorder.before }}</view>
      <view>现大小：{{ compreeRecorder.after }}</view>
      <view>压缩率：{{ compreeRecorder.rate }}</view>
      <view>压缩时长：{{ `${compreeRecorder.time}(${compreeRecorder.speed})` }}</view>
      <view>压缩1GB约：{{ compreeRecorder._1GB_duration }}</view>
      <ve-button style="margin-top: 20rpx" @click="copyCompressText">复制并关闭</ve-button>
    </view>
  </view>
</template>

<script>
  // #ifdef APP-PLUS
  import permision from '@/utils/permissionCheck/permission.js'
  // #endif
  import { getFileSingle } from '@/api/common'
  import { packagedUploadFile } from '@/utils/upload-tool'
  export default {
    props: {
      // 视频fileId集合
      modelValue: Array,
      // 只读，隐藏视频删除icon
      readonly: {
        type: Boolean,
        default: false,
      },
      maxMB: {
        type: Number,
        // default: 800,
      },
    },
    data() {
      const env = getApp().globalData.env
      const showLog = ['test02', 'test', 'dev'].includes(env)
      return {
        videoObj: null,
        progressInfo: {
          visible: false,
          uploadTask: null,
          percent: 0,
        },
        // 是否显示压缩信息
        showLog,
        // 压缩调试配置
        compreeRecorder: {
          visible: false,
        },
      }
    },
    watch: {
      modelValue: {
        handler(val) {
          if (val) {
            this.getVideo(val[0])
          }
        },
        immediate: true,
      },
    },
    methods: {
      // 获取视频信息
      getVideo(val) {
        if (val) {
          getFileSingle({ id: val }).then((res) => {
            if (res.code == 200 && res.result) {
              const result = res.result
              this.videoObj = {
                openUrl: result.openUrl,
                fileIdStr: result.fileIdStr,
              }
            }
          })
        }
      },
      // 视频出错
      videoErrorCallback: function (e) {
        uni.showModal({
          content: e.target.errMsg,
          showCancel: false,
        })
      },
      // 视频删除
      delVideo() {
        uni.showModal({
          title: '提示',
          content: '是否确认删除？',
          success: (res) => {
            if (res.confirm) {
              this.videoObj = null
              this.handleUpload()
            }
          },
        })
      },
      /**
       * 更新数据
       */
      handleUpload() {
        let videoObj = this.videoObj
        const newValue = videoObj ? [videoObj.fileIdStr] : null
        this.$emit('update:modelValue', newValue)
        this.$emit('change', newValue)
      },
      /**
       * 压缩图片
       * @param {string} tempFilePath 临时路径
       * */
      async compressVideo(tempFilePath) {
        return new Promise((resolve, reject) => {
          uni.getVideoInfo({
            src: tempFilePath,
            success: (info) => {
              console.log('uploadVideo===开始压缩视频===视频信息：', info)
              uni.showLoading({
                title: '压缩中...',
                icon: 'loading',
                // 防止触摸透穿
                mask: true,
              })
              uni.compressVideo({
                src: tempFilePath,
                quality: 'medium',
                success: (res) => {
                  // 压缩后记录文件大小
                  this.compreeRecorder.afterSize = res.size
                  console.log('uploadVideo===结束压缩视频===视频大小：', res.size)
                  resolve(res.tempFilePath)
                  uni.hideLoading()
                },
                fail(err) {
                  reject(err)
                  uni.hideLoading()
                },
              })
            },
          })
        })
      },
      // 选择视频
      chooseVideo() {
        uni.chooseVideo({
          compressed: false,
          sourceType: ['album'],
          success: async (res) => {
            const tempFilePath = res.tempFilePath
            let compressFilePath = null
            const mbSize = Number((res.size / (1024 * 1024)).toFixed(2))
            if (this.maxMB) {
              const maxSize = this.maxMB * 1024 * 1024
              if (res.size > maxSize) {
                return uni.showModal({
                  title: '警告',
                  showCancel: false,
                  content: `请选择不超过${this.maxMB}MB的文件, 当前文件${mbSize}MB`,
                })
              }
            }
            // 30mb以上的视频才压缩
            // 去压缩
            if (mbSize > 31) {
              console.log('uploadVideo===开始压缩视频===视频大小(MB)：', mbSize)
              // 压缩前记录文件大小
              this.compreeRecorder.beforeSize = res.size
              // 压缩前记录当前时间
              this.compreeRecorder.compressBegin = new Date().getTime()
              // 压缩视频
              compressFilePath = await this.compressVideo(tempFilePath)
              // 压缩后记录当前时间
              this.compreeRecorder.compressEnd = new Date().getTime()
              // #ifdef APP-PLUS
              this.openCompressResult()
              // #endif
            }
            // 上传视频
            this.progressInfo.uploadTask = packagedUploadFile({
              filePath: compressFilePath || tempFilePath,
              success: (res) => {
                console.log('uploadVideo===上传视频===成功，', res)
                if (res.statusCode == 200) {
                  res.data = JSON.parse(res.data)
                  this.videoObj = {
                    openUrl: res.data.result[0].openUrl,
                    fileIdStr: res.data.result[0].fileIdStr,
                  }
                  this.handleUpload()
                } else {
                  uni.showToast({
                    title: res.data.message ? res.data.message : '网络异常,请稍后再试',
                    icon: 'none',
                  })
                }
              },
              fail: (err) => {
                console.log('uploadVideo===上传视频===失败，', err)
                const errMsg = err.errMsg
                // 手动调用的 abort，会报 uploadFile:fail abort 或 uploadFile:fail statusCode: null
                if (!['uploadFile:fail abort', 'uploadFile:fail statusCode: null'].includes(errMsg)) {
                  uni.showToast({
                    title: '网络异常,请稍后再试',
                    icon: 'none',
                  })
                }
              },
              complete: () => {
                this.resetUpload()
                // #ifdef APP-PLUS
                uni.removeSavedFile({
                  filePath: tempFilePath,
                })
                if (compressFilePath) {
                  uni.removeSavedFile({
                    filePath: compressFilePath,
                  })
                }
                // #endif
              },
            })
            this.progressInfo.visible = true
            this.progressInfo.uploadTask.onProgressUpdate((res) => {
              this.progressInfo.percent = res.progress
            })
          },
        })
      },
      // 视频上传
      upMaintainVideo() {
        const system = uni.getSystemInfoSync()
        console.log('uploadVideo===上传格式，', system.osName)
        if (system.osName == 'android') {
          permision.premissionCheck('EXTERNAL_STORAGE').then((premissionRes) => {
            if (premissionRes == 1) {
              this.chooseVideo()
            }
          })
          return
        }
        this.chooseVideo()
      },
      // 上传信息重置
      resetUpload() {
        this.progressInfo.visible = false
        this.progressInfo.uploadTask = null
        this.progressInfo.percent = 0
      },
      // 取消上传
      cancelUpload() {
        let task = this.progressInfo.uploadTask
        if (task) {
          task.offProgressUpdate()
          task.abort()
        }
        // 关闭上传进度弹框
        this.resetUpload()
      },
      // 开启结果
      openCompressResult() {
        const beforeSize = this.compreeRecorder.beforeSize
        const afterSize = this.compreeRecorder.afterSize
        const compressBegin = this.compreeRecorder.compressBegin
        const compressEnd = this.compreeRecorder.compressEnd
        // 字节转换为MB
        const addMb = (size) => {
          return `${Number((size / (1024 * 1024)).toFixed(2))}`
        }
        // 压缩前大小
        this.compreeRecorder.before = addMb(beforeSize) + 'MB'
        this.compreeRecorder.after = addMb(afterSize) + 'MB'
        // 压缩时长
        const seconds = Math.floor((compressEnd - compressBegin) / 1000)
        const minutes = Math.floor(seconds / 60)
        const remainingSeconds = Math.floor(seconds % 60)
        if (minutes > 0) {
          this.compreeRecorder.time = `${minutes}分${remainingSeconds}秒`
        } else {
          this.compreeRecorder.time = `${remainingSeconds}秒`
        }
        // 压缩效率
        const speed = addMb(beforeSize) / seconds // 单位MB/s
        this.compreeRecorder.speed = speed.toFixed(2) + 'MB/s'
        // 压缩一分钟约的时长（单位s）
        const compress1GbSeconds = Math.floor((seconds * 1024) / addMb(beforeSize))
        const compress1GbMinutes = Math.floor(compress1GbSeconds / 60)
        const compress1GbRemainingSeconds = Math.floor(compress1GbSeconds % 60)
        if (compress1GbMinutes > 0) {
          this.compreeRecorder._1GB_duration = `${compress1GbMinutes}分${compress1GbRemainingSeconds}秒`
        } else {
          this.compreeRecorder._1GB_duration = `${compress1GbRemainingSeconds}秒`
        }
        // 压缩率
        this.compreeRecorder.rate = Math.ceil(((beforeSize - afterSize) / beforeSize) * 100) + '%'
        // 打开结果
        this.compreeRecorder.visible = true
      },
      // 复制压缩信息
      copyCompressText() {
        uni.setClipboardData({
          data:
            `原大小：${this.compreeRecorder.before}\n` +
            `现大小：${this.compreeRecorder.after}\n` +
            `压缩率：${this.compreeRecorder.rate}\n` +
            `压缩时长：${this.compreeRecorder.time}(${this.compreeRecorder.speed}) \n` +
            `压缩1GB约：${this.compreeRecorder._1GB_duration}`,
          success: () => {
            this.compreeRecorder.visible = false
          },
        })
      },
    },
    computed: {},
    mounted() {},
  }
</script>
<style lang="scss" scoped>
  .add_btn {
    display: inline-block;
    width: 41rpx;
  }
  .video-wrapper {
    width: 100%;
    .upload-wrapper {
      // 16 / 9 比例
      width: 100%;
      padding-bottom: 56.25%;
      position: relative;
      .upload {
        position: absolute;
        width: 100%;
        height: 100%;
        left: 0;
        top: 0;

        border-radius: 8rpx;
        border: 2rpx dashed #9ea5bb;
        display: flex;
        flex-direction: column;
        padding: 0 10rpx;
        text-align: center;
        .tips {
          .tips-text {
            margin-top: 18rpx;
            color: #9ea5bb;
          }
          .tips-text.red {
            margin-top: 6rpx;
            color: #f53f3f;
          }
        }
      }
    }
  }
  .flex-row-center {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: center;
  }
  .empty-block {
    width: 100%;
    padding-bottom: 56.25%;
    position: relative;
    .empty-block-wrap {
      position: absolute;
      width: 100%;
      height: 100%;
      left: 0;
      top: 0;
      display: flex;
      align-items: center;
      justify-content: center;
      border-radius: 4rpx 4rpx 4rpx 4rpx;
      text-align: center;
      background: #f2f3f5;
      border: 1px solid #e2e2e2;
      font-size: 24rpx;
      color: #b6b6b6;
      line-height: 40rpx;
    }
  }

  .u-toast-container {
    position: fixed;
    top: 0;
    right: 0;
    width: 400rpx;
    background-color: rgb(0, 0, 0, 0.6);
    z-index: 9999;
    padding: 20rpx;
    color: #fff;
    line-height: 40rpx;
  }
</style>
